package canglang.monitor.core.codelookup.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

@SuppressWarnings("unchecked")
public class CodeLookupConfig {
	private static String CODELOOKUP_CONFIG_XML = "codelookup-config.xml";
    private static Object initLock = new Object();
    private static CodeLookupConfig instance;
    private Logger logger;
    
    private List codeLookupBeans;
    
    private CodeLookupConfig() {
    	logger = Logger.getLogger(this.getClass());
    	codeLookupBeans = new ArrayList();
    }
    
    public static CodeLookupConfig getInstance() throws RuntimeException {
        if (instance == null) {
            synchronized (initLock) {
                if (instance == null) {
                    instance = new CodeLookupConfig();
                    instance.parse();
                }
            }
        }
        return instance;
    }
    
    private void parse() throws RuntimeException {
    	/*
    	 <codelookup-config>         
    	 <codelookup code-type="CNTY" 
                    code-table="LCNTY" 
                    code-desc-col="CNTYDESC"
                    code-id-col="CNTYCD">
         </codelookup>        
        
         <codelookup code-type="NAT"
                    code-table="LNATNCD"
                    code-desc-col="NATDESC"
                    code-id-col="NATCD">

            <obsolete-ind
                    eff-start-dt-col="DTEFF"
                    eff-end-dt-col="DTEND">
            </obsolete-ind>

            <sql-filter name="A">
                    POLTGRPCD = ? and CENSCD = ?
            </sql-filter>

            <sql-filter name="B">
                    MJRCNTYCD = ?
            </sql-filter>
         </codelookup>

         <codelookup code-type="LABEL"
                    code-table="LLABELCD"
                    code-desc-col="CDDESC"
                    code-id-col="LABCODE">

            <obsolete-ind obsolete-col="OBSOLETE">
                    <obsolete-val>T</obsolete-val>
                    <obsolete-val>Y</obsolete-val>
            </obsolete-ind>

            <sql-filter name="labeltype">
                  LABTYPE = ?
            </sql-filter>
         </codelookup>
         </codelookup-config>
    	 */
    	InputStream in = this.getClass().getClassLoader().getResourceAsStream(CODELOOKUP_CONFIG_XML);
        try {
            Digester digester = new Digester();
            digester.push(instance);
    		digester.addObjectCreate("codelookup-config/codelookup", CodeLookupBean.class);

    		digester.addSetProperties("codelookup-config/codelookup");
    		digester.addSetProperties("codelookup-config/codelookup", "code-type", "codeType");
    		digester.addSetProperties("codelookup-config/codelookup", "code-table", "codeTable");
    		digester.addSetProperties("codelookup-config/codelookup", "code-desc-col", "codeDescCol");
    		digester.addSetProperties("codelookup-config/codelookup", "code-id-col", "codeIdCol");

    		digester.addSetProperties("codelookup-config/codelookup/obsolete-ind", "eff-start-dt-col", "effStartDtCol");
    		digester.addSetProperties("codelookup-config/codelookup/obsolete-ind", "eff-end-dt-col", "effEndDtCol");
    		digester.addSetProperties("codelookup-config/codelookup/obsolete-ind", "obsolete-col", "obsoleteCol");

    		digester.addCallMethod("codelookup-config/codelookup/obsolete-ind/obsolete-val", "addObsoleteValue", 1);
    		digester.addCallParam("codelookup-config/codelookup/obsolete-ind/obsolete-val", 0);

    		digester.addCallMethod("codelookup-config/codelookup/sql-filter", "addSqlFilter", 2);
    		digester.addCallParam("codelookup-config/codelookup/sql-filter", 0, "name");
    		digester.addCallParam("codelookup-config/codelookup/sql-filter", 1);

    		digester.addSetNext("codelookup-config/codelookup", "addCodeLookupBean");
    		digester.parse(in);
		} catch (IOException ex) {
			logger.error("Error in parsing [" + CODELOOKUP_CONFIG_XML + "]", ex);
			throw new RuntimeException(ex);
		} catch (SAXException ex) {
			logger.error("Error in parsing [" + CODELOOKUP_CONFIG_XML + "]", ex);
			throw new RuntimeException(ex);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException ex) {
				}
			}
		}
    }
    
    public CodeLookupBean getCodeLookup(String codeType) {
    	CodeLookupBean codeLookupBean = null;
    	for (int i=0; i<codeLookupBeans.size(); i++) {
    		codeLookupBean = (CodeLookupBean)codeLookupBeans.get(i);
    		if (codeLookupBean.getCodeType().equals(codeType)) {
    			return codeLookupBean;
    		}
    	}
    	return codeLookupBean;
    }
    
    public void addCodeLookupBean(CodeLookupBean codeLookupBean) {
    	codeLookupBeans.add(codeLookupBean);
    }

    //FIXME: testing...
    public void print() {
		for (int i = 0; i < codeLookupBeans.size(); i++ ) {
			CodeLookupBean bean = (CodeLookupBean)codeLookupBeans.get(i);
			System.out.println( i + " -  " + bean + "\n");
		}
	}
}